from io import BytesIO
from typing import Dict

from fastapi import APIRouter
from matplotlib import pyplot as plt
from minio.error import S3Error

from common.method import *
from common.model import InterpolationData
from common.params import ReqSoftParams, SoftParams
from service.DataPreService import read_interpolation_data
from model.soft.cable_tension import run as cable_run
from model.soft.safe_cable_tension import run as safe_cable_run
from model.soft.pull_tension import run as pull_tension_run


router = APIRouter()
from strain.cable_strain import run as strain_run

@router.post('/v3/strain/data')
async def cable_strain_data(params: ReqSoftParams):
    # 计算 MD5 哈希值
    md5_hash = params.calc_md5()
    # 获取井号
    wellId: str = params.wellId
    # 获取间距
    space: float = params.space
    # 获取是否有造斜点
    is_slanting_point = params.is_slanting_point
    # 构建对象名称
    data_object_name = wellId + '/' + md5_hash + '-strain.xlsx'
    print(data_object_name)
    # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
    is_Not_add_resistance = params.add_liquid_resistance
    try:
        client.stat_object('well', data_object_name)
        print('已存在对应变形量分析数据')
        file_data = client.get_object("well", data_object_name)
        df = pd.read_excel(BytesIO(file_data.read()))
        data_list = []
        for index, row in df.iterrows():
            data_list.append(row)
        return data_list
    except S3Error:
        print('不存在变形量分析数据')
    # 参数预处理
    soft_params: SoftParams = SoftParams(params)

    # 获取插值数据
    _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
    max_depth: float = _list_[-1].depth
    inc_dict: Dict = {}
    for item in _list_:
        inc_dict[item.depth] = item.inclination
    # soft_params.build_f_hel(inc_dict, max_depth)
    # for item in soft_params.f_hel_dict:
    #     print(item, soft_params.get_f_hel(item))
    # _list_ = get_test_data()
    # 计算的间距
    calculate_space = params.calculate_space
    last_depth = _list_[-1].depth
    # 设置间隔深度列表
    desired_depths = [last_depth]
    # 从最后一个深度开始，减去间距，直到小于间距为止 这样就只计算部分深度
    while desired_depths[-1] > calculate_space:
        new_value = desired_depths[-1] - calculate_space
        desired_depths.append(new_value)
        # 对列表进行排序并去除重复值
    desired_depths = sorted(set(desired_depths), reverse=True)
    # desired_depths = [1875.0,1874.0,1800.0]


    # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
    is_Not_add_resistance = params.add_liquid_resistance
    # 井口摩擦力设置
    wellhead_friction: float = params.wellhead_friction
    result = strain_run(soft_params, _list_, is_Not_add_resistance, desired_depths, wellhead_friction)
    save('well', data_object_name, result)
    return result


# 叠加变形量画图
@router.post("/v3/strain/draw")
async def cable_strain_draw(params: ReqSoftParams):
    # 计算 MD5 哈希值
    md5_hash = params.calc_md5()
    # 获取井号
    wellId: str = params.wellId
    # 获取间距
    space: float = params.space
    # 获取是否有造斜点
    is_slanting_point = params.is_slanting_point
    # 构建对象名称
    image_object_name = wellId + '/' + md5_hash + '-变形量分析图.png'
    # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
    is_Not_add_resistance = params.add_liquid_resistance
    try:
        client.stat_object('well', image_object_name)
        print('已存在对应变形量分析图')
        return {
            'bucketName': 'well',
            'objectName': image_object_name
        }
    except S3Error:
        print('不存在对应变形量分析图')
    # 参数预处理
    soft_params: SoftParams = SoftParams(params)
    # 获取插值数据
    _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
    max_depth: float = _list_[-1].depth
    inc_dict: Dict = {}
    for item in _list_:
        inc_dict[item.depth] = item.inclination
    # soft_params.build_f_hel(inc_dict, max_depth)
    # _list_ = get_test_data()
    # 计算的间距
    calculate_space = params.calculate_space
    last_depth = _list_[-1].depth
    # 设置间隔深度列表
    desired_depths = [last_depth]
    # 从最后一个深度开始，减去间距，直到小于间距为止 这样就只计算部分深度
    while desired_depths[-1] > calculate_space:
        new_value = desired_depths[-1] - calculate_space
        desired_depths.append(new_value)
        # 对列表进行排序并去除重复值
    desired_depths = sorted(set(desired_depths), reverse=True)

    # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
    is_Not_add_resistance = params.add_liquid_resistance
    # 井口摩擦力设置
    wellhead_friction: float = params.wellhead_friction
    result = strain_run(soft_params, _list_, is_Not_add_resistance, desired_depths, wellhead_friction)
    # for item in result:
    #     print(JsonUtil.obj2str(item))
    # return 0.0
    depth_list = [item.depth for item in result]
    push_list = [item.all_strain_push for item in result]
    pull_list = [item.all_strain_pull for item in result]
    plt.rcParams['font.sans-serif'] = ["SimHei"]
    plt.rcParams['axes.unicode_minus'] = True  # 解决坐标轴负号显示问题
    fig, ax = plt.subplots()
    ax.plot(push_list, depth_list, color='r', label='下放叠加形变量')
    ax.plot(pull_list, depth_list, color='g', label='上提叠加形变量')
    ax.xaxis.set_label_coords(0.5, 1.1)
    ax.xaxis.tick_top()
    ax.invert_yaxis()
    # plt.scatter(force_list, depth_list, marker='.', edgecolors='k')
    # 添加标题和标签
    plt.title("变形量分析图", loc='left', pad=5)
    plt.xlabel("变形量(m)")
    plt.ylabel("深度(m)")
    plt.legend()
    # plt.show()
    buffer = BytesIO()
    plt.savefig(buffer, format='png')
    buffer.seek(0)
    # 上传文件
    putObject("well", image_object_name, buffer)
    return {
        'bucketName': 'well',
        'objectName': image_object_name
    }


from model.soft.descent_depth import run as descent_run

# 4.2 到达深度分析 +  4.3 井底受力分析
@router.post("/v3/descent/conclusion")
async def cable_descent_conclusion(params: ReqSoftParams):
    # 计算 MD5 哈希值
    md5_hash = params.calc_md5()
    # 参数预处理
    soft_params: SoftParams = SoftParams(params)
    # 获取井号
    wellId: str = params.wellId
    # 获取间距
    space: float = params.space
    # 获取是否有造斜点
    is_slanting_point = params.is_slanting_point
    # 构建对象名称
    data_object_name_cable_strain = wellId + '/' + md5_hash + '-strain.xlsx'
    # 构建张力对象名称
    data_object_name_cable_tension = wellId + '/' + md5_hash + '-cable_tension.xlsx'
    # 构建上提张力对象名称
    data_object_name_pull_tension = wellId + '/' + md5_hash + '-pull_tension.xlsx'
    # 构建可下入深度对象名称
    data_object_name_descent_depth = wellId + '/' + md5_hash + '-descent_depth.xlsx'
    # 构建安全操作时缆头张力对象名称
    data_object_name_safe_cable = wellId + '/' + md5_hash + '-safe_cable.xlsx'
    result_cable_strain = []
    result_cable_tension = []
    result_pull_tension = []
    result_descent_depth = []
    result_safe_cable = []
    # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
    is_Not_add_resistance = params.add_liquid_resistance
    try:
        client.stat_object('well', data_object_name_cable_strain)
        print('已存在对应变形量分析数据')
        file_data = client.get_object("well", data_object_name_cable_strain)
        df = pd.read_excel(BytesIO(file_data.read()))
        result_cable_strain = []
        for index, row in df.iterrows():
            result_cable_strain.append(row)
    except S3Error:
        print('不存在变形量分析数据')
        # 获取插值数据
        _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
        max_depth: float = _list_[-1].depth
        inc_dict: Dict = {}
        for item in _list_:
            inc_dict[item.depth] = item.inclination
        # soft_params.build_f_hel(inc_dict, max_depth)
        # 计算的间距
        calculate_space = params.calculate_space
        last_depth = _list_[-1].depth
        # 设置间隔深度列表
        desired_depths = [last_depth]
        # 从最后一个深度开始，减去间距，直到小于间距为止 这样就只计算部分深度
        while desired_depths[-1] > calculate_space:
            new_value = desired_depths[-1] - calculate_space
            desired_depths.append(new_value)
            # 对列表进行排序并去除重复值
        desired_depths = sorted(set(desired_depths), reverse=True)

        # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
        is_Not_add_resistance = params.add_liquid_resistance
        # 井口摩擦力设置
        wellhead_friction: float = params.wellhead_friction
        result_cable_strain = strain_run(soft_params, _list_, is_Not_add_resistance, desired_depths, wellhead_friction)
        save('well', data_object_name_cable_strain, result_cable_strain)
    try:
        client.stat_object('well', data_object_name_cable_tension)
        print('已存在对应缆头张力分析数据')
        file_data = client.get_object("well", data_object_name_cable_tension)
        df = pd.read_excel(BytesIO(file_data.read()))
        result_cable_tension = []
        for index, row in df.iterrows():
            result_cable_tension.append(row)
    except S3Error:
        print('不存在缆头张力分析分析数据')
        # 获取插值数据
        _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
        max_depth: float = _list_[-1].depth
        inc_dict: Dict = {}
        for item in _list_:
            inc_dict[item.depth] = item.inclination
        # soft_params.build_f_hel(inc_dict, max_depth)
        # 计算的间距
        calculate_space = params.calculate_space
        last_depth = _list_[-1].depth
        # 设置间隔深度列表
        desired_depths = [last_depth]
        # 从最后一个深度开始，减去间距，直到小于间距为止 这样就只计算部分深度
        while desired_depths[-1] > calculate_space:
            new_value = desired_depths[-1] - calculate_space
            desired_depths.append(new_value)
            # 对列表进行排序并去除重复值
        desired_depths = sorted(set(desired_depths), reverse=True)

        # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
        is_Not_add_resistance = params.add_liquid_resistance
        result_cable_tension = cable_run(soft_params, _list_, is_Not_add_resistance, desired_depths)
        save('well', data_object_name_cable_tension, result_cable_tension)

    try:
        client.stat_object('well', data_object_name_pull_tension)
        print('已存在对应上提张力数据')
        file_data = client.get_object("well", data_object_name_pull_tension)
        df = pd.read_excel(BytesIO(file_data.read()))
        result_pull_tension = []
        for index, row in df.iterrows():
            result_pull_tension.append(row)
    except S3Error:
        print('不存在对应上提张力数据')
        soft_params: SoftParams = SoftParams(params)
        # 获取插值数据
        _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
        result_pull_tension = pull_tension_run(soft_params, _list_, is_Not_add_resistance)
        save('well', data_object_name_pull_tension, result_pull_tension)
    try:
        client.stat_object('well', data_object_name_descent_depth)
        print('已存在对应可下入深度分析数据')
        file_data = client.get_object("well", data_object_name_descent_depth)
        df = pd.read_excel(BytesIO(file_data.read()))
        result_descent_depth = []
        for index, row in df.iterrows():
            result_descent_depth.append(row)
    except S3Error:
        print('不存在可下入深度分析分析数据')
        # 获取插值数据
        _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
        inc_depth: float = _list_[-1].depth
        # 获取给定的井斜角的值
        inc_value = params.inclination
        inc_dict: Dict = {}
        for item in _list_:
            inc_dict[item.depth] = item.inclination
            if item.inclination > inc_value:
                inc_depth = item.depth
                break
        print("当前的井斜角对应的深度为为", inc_depth)
        # 计算的间距
        calculate_space = params.calculate_space
        last_depth = _list_[-1].depth
        # 设置间隔深度列表
        desired_depths = [last_depth]
        # 从最后一个深度开始，减去间距，直到小于间距为止 这样就只计算部分深度
        while desired_depths[-1] > calculate_space:
            new_value = desired_depths[-1] - calculate_space
            desired_depths.append(new_value)
            # 对列表进行排序并去除重复值
        desired_depths = sorted(set(desired_depths), reverse=True)

        # 是否加入液体阻力 @TODO 如果为true就加入 否则加0
        is_Not_add_resistance = params.add_liquid_resistance
        # print(inc_dict)
        result_descent_depth = descent_run(soft_params, inc_depth, _list_, is_Not_add_resistance, desired_depths)
        save('well', data_object_name_descent_depth, result_descent_depth)
    try:
        client.stat_object('well', data_object_name_safe_cable)
        print('已存在对应安全操作时的缆头张力分析数据')
        file_data = client.get_object("well", data_object_name_safe_cable)
        df = pd.read_excel(BytesIO(file_data.read()))
        result_safe_cable = []
        for index, row in df.iterrows():
            result_safe_cable.append(row)
    except S3Error:
        print('不存在对应安全操作时的缆头张力分析数据')
        # 参数预处理
        soft_params: SoftParams = SoftParams(params)
        # 获取插值数据
        _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
        inc_depth: float = _list_[-1].depth
        # ********************************************
        # # 拿到拦截的极限下入深度
        descent_depth_point: float = result_descent_depth[0].depth
        # 是否可以下入到极限深度：井底 能下入就是 True 不能正常就是False
        is_not_descent_bottom: bool = True

        for descent_item in result_descent_depth:
            if descent_item.push_cable_pressure == 1:
                is_not_descent_bottom = False
                descent_depth_point = descent_item.depth
        # ********************************************
        # 获取总长度
        all_depth: float = _list_[-1].depth - _list_[0].depth
        # 设置间隔
        interval: float = 300
        # 设置间隔深度列表---存放绞车操作表的井深
        desired_depths = []
        for depth_item in _list_:
            if depth_item.depth > 0:
                depth_diff = depth_item.depth - _list_[0].depth
                if depth_diff % interval == 0 or (
                        is_not_descent_bottom == False and depth_item.depth == descent_depth_point):
                    desired_depths.append(depth_item.depth)
        desired_depths.reverse()
        print(desired_depths)
        print("************")
        # 获取给定的拉断力、置信度和安全操作拉力百分比
        operatingLoad: float = params.operatingLoad / 100
        # 将拉断力由千牛转换为牛
        F_break: float = params.F_break * 1000 * operatingLoad
        # F_break: float = params.F_break * 1000
        confidence_level: float = params.confidence_level
        # 井口摩擦力设置
        wellhead_friction: float = params.wellhead_friction
        # 上下限
        range_left: float = F_break * confidence_level - wellhead_friction
        range_right: float = F_break - wellhead_friction
        # 取值上下范围
        left: float = 0
        right: float = F_break - wellhead_friction
        mid: float = int((left + right) / 2)
        sc = {
            'depth': inc_depth
        }
        if is_not_descent_bottom:
            sc['depth'] = inc_depth
        else:
            sc['depth'] = descent_depth_point

        result_safe_cable = []  # 创建一个列表用于存储所有截断的结果
        while sc['depth'] >= params.L1:
            # 取值上下范围
            left: float = 0
            right: float = F_break - wellhead_friction
            # 中值计算
            while right >= left:
                mid: int = int((left + right) / 2)
                # print("mid取值:{}, left为:{} right为:{}".format(mid, left, right))
                # _list_ 根据当前深度截取 > sc[depth] 全部截取掉
                t_list = []
                for item in _list_:
                    if (item.depth <= sc['depth']):
                        t_list.append(item)
                sc = safe_cable_run(soft_params, t_list, mid, desired_depths, wellhead_friction)
                if sc['result']:
                    # print(JsonUtil.obj2str(sc['result']))
                    # 将当前结果添加到列表中
                    result_safe_cable.extend(sc['result'])
                if sc['ok']:
                    break
                else:
                    compare_val = sc['f_pull']
                    # print("compare_val", compare_val)
                    if compare_val > range_right:
                        right = mid - 1
                    elif compare_val < range_left:
                        left = mid + 1

                # print(JsonUtil.obj2str(sc['result']))
        save('well', data_object_name_safe_cable, result_safe_cable)
    _list_: List[InterpolationData] = read_interpolation_data(wellId, space, is_slanting_point)
    inclinations: float = params.inclination
    # 狗腿度最严重的位置
    max_dog_leg_severity_depth: float = 0.0
    max_dog_leg_severity: float = 0.0
    for item in _list_:
        # 计算最大狗腿度
        if item.dog_leg_severity > max_dog_leg_severity:
            max_dog_leg_severity = item.dog_leg_severity
            max_dog_leg_severity_depth = item.depth

    # 判断是不是发生螺旋屈曲 给电缆是否压缩进行传值
    has_compress_pull: bool = False
    has_compress_push: bool = False
    for f_item in result_cable_strain:
        if f_item.compress_push == 1:
            has_compress_push = True
        if f_item.compress_pull == 1:
            has_compress_pull = True
    # **************************************
    # 3.6修改可下入深度
    descent_depth_point: float = result_descent_depth[0].depth
    # 是否可以下入到极限深度：井底 能下入就是 True 不能正常就是False
    pressure_low_depth = 0
    pressure_high_depth = 0
    # # 拿到拦截的极限下入深度
    hel_depth: float = result_descent_depth[0].depth
    # 是否可以下入到极限深度：井底 能下入就是 True 不能正常就是False
    is_not_descent_bottom: bool = True
    for descent_item in result_descent_depth:
        if descent_item.push_cable_pressure == 1:
            is_not_descent_bottom = False
            pressure_low_depth = descent_item.pressure_low_depth
            pressure_high_depth = descent_item.pressure_high_depth
            descent_depth_point = descent_item.depth
            hel_depth = descent_item.depth
    # print("is_not_descent_bottom",is_not_descent_bottom)
    # print("pressure_low_depth",pressure_low_depth)
    # print("pressure_high_depth",pressure_high_depth)
    # print("descent_depth_point",descent_depth_point)
    # 发生屈曲的迭代开始深度 start_depth 1890 屈曲点 hel_depth 1843
    start_depth: float = 0.0
    # 获取 1883 全部值
    target_item = result_cable_strain[0].F_weak_rate_low
    for f_item in result_cable_strain:
        if f_item.depth == hel_depth:
            target_item = f_item
            break
    # ********************************************
    m1: float = params.m1
    ground_tension: float = round(result_cable_strain[0].F_weak_rate_low / 1000, 2)
    bottom_push: float = result_cable_strain[0].all_strain_push
    bottom_pull: float = result_cable_strain[0].all_strain_pull
    # 正常下入时 用低弱点的70%，不要提取数据，就用低弱点的70%即可

    if is_not_descent_bottom == False:
        bottom_push: float = target_item.all_strain_push
        bottom_pull: float = target_item.all_strain_pull
    # 计算比例rate
    rate: float = round(params.F_weak_rate_low / params.F_weak_low, 2)
    base_val: int = round((params.F_weak_low + params.F_weak_high) / 8.9)
    pull_cable_tension: float = result_cable_tension[0].F_pull
    for cable_item in result_cable_tension:
        if cable_item.depth == hel_depth:
            pull_cable_tension = cable_item.F_pull
    # 最新超拉力
    new_max_super_pull: float = round(rate * base_val / 1000 * 4.45 - pull_cable_tension / 1000, 2)
    new_max_super_pull_weight_rate: float = round(new_max_super_pull / (m1 * params.L1 * 9.81 / 1000), 2)
    # 最新地面显示张力值
    new_ground_tension: float = round(result_pull_tension[0].F / 1000, 2)

    # 获取给定的拉断力、置信度和安全操作拉力百分比
    operatingLoad: float = params.operatingLoad / 100
    # 将拉断力由千牛转换为牛
    F_break: float = params.F_break * operatingLoad

    pull_safe_cable: float = result_safe_cable[0].F_pull
    for safe_cable_item in result_safe_cable:
        if safe_cable_item.depth == hel_depth:
            pull_safe_cable = safe_cable_item.F_pull

    # 在判断电缆最大超拉力的时候此处用安全操作时的缆头张力
    # 最大超拉力计算：查询井底处的安全操作时的缆头张力，减去井底处的正常上提缆头张力，比如如果井底处的上提缆头张力是2.96kN，即45.20-2.96=42.24kN
    # safe_cable_max_super_force: float = round(result_safe_cable[0].F_pull / 1000 - result_cable_tension[0].F_pull / 1000, 2)
    safe_cable_max_super_force: float = round(pull_safe_cable / 1000 - pull_cable_tension / 1000, 2)
    # 最大超拉力是仪器在空气中重量的10378%。
    # print("(m1 * params.L1 * 9.81 / 1000)",(m1 * params.L1 * 9.81 / 1000))
    if is_not_descent_bottom == False:
        safe_cable_max_super_force: float = round(pull_safe_cable / 1000 - pull_cable_tension / 1000, 2)
    safe_max_super_force_weight_rate: float = round(safe_cable_max_super_force / (m1 * params.L1 * 9.81 / 1000), 2)

    # 如果是要英制单位 就将公制转换英制 1KN = 224.81 lbf
    if params.is_Not_metric == False:
        new_max_super_pull: float = round((rate * base_val / 1000 * 4.45 - pull_cable_tension / 1000) * 224.81, 2)
        new_ground_tension: float = round((result_pull_tension[0].F / 1000) * 224.81, 2)
        F_break: float = params.F_break * operatingLoad * 224.81
        safe_cable_max_super_force: float = round((pull_safe_cable / 1000 - pull_cable_tension / 1000) * 224.81, 2)
    return {
        # 是否正常下入到井底 原来使用电缆形变量中的参数is_not_enter_depth，现在需要使用极限下入深度中的数据
        # "is_not_enter_depth": is_not_enter_depth,
        "is_not_enter_depth": is_not_descent_bottom,
        # 1.下放：仪器组合可以到达目的深度Dm。
        # 2.上提：仪器组合可以由目的深度Dm处返回地面。
        # 4.按照现有参数，仪器组合不需要爬行器牵引以达到目的深度m。
        # 注意 原来使用的是屈曲点
        # "f_descent_hel_depth": hel_depth,
        # 现在请使用 极限下入深度中的数据
        "f_descent_hel_depth": descent_depth_point,
        # 无法到达深度2100
        "not_descent_depth": result_cable_strain[0].depth,
        # 受压点低深度
        "pressure_low_depth": pressure_low_depth,
        # 受压点高深度
        "pressure_high_depth": pressure_high_depth,
        # 电缆无压缩 弱点张力不超过极限
        "has_compress_push": has_compress_push,
        "has_compress_pull": has_compress_pull,
        # 3.井-XXX在井深为216.0m时的狗腿度最为严重，为14.62（°/30m）。
        "max_dog_leg_severity_depth": max_dog_leg_severity_depth,
        "max_dog_leg_severity": round(max_dog_leg_severity, 2),
        # ********

        # 基于弱点拉断力的70 %
        "rate": rate,
        # 在2100m处最大超拉力为47.81kN
        "max_super_pull": new_max_super_pull,
        # 地面显示张力值为50.77kN
        "ground_tension": new_ground_tension,
        # 最大超拉力是仪器串在空气中重量的1174%
        "max_super_pull_weight_rate": round(new_max_super_pull_weight_rate * 100, 2),
        # 下放时电缆在2100m处拉伸长度为0.33m
        "bottom_push": bottom_push,
        # 上提时电缆在2100m处拉伸长度为1.50m
        "bottom_pull": bottom_pull,

        # 基于电缆拉断力的100%
        "operatingLoad": params.operatingLoad,
        # 即拉力89kN
        "safe_cable_f_break": F_break,
        # 在2100m（井底）处最大超拉力为42.24kN。
        # "safe_cable_bottom_depth": result_safe_cable[0].depth,
        "safe_cable_bottom_depth": descent_depth_point,
        # 最大超拉力计算：查询井底处的安全操作时的缆头张力，减去井底处的正常上提缆头张力，比如如果井底处的上提缆头张力是2.96kN，即45.20-2.96=42.24kN
        "safe_cable_max_super_force": safe_cable_max_super_force,
        # 最大超拉力是仪器在空气中重量的10378%。
        "safe_max_super_force_weight_rate": safe_max_super_force_weight_rate * 100

    }